package trans.main;
import java.io.*;
import java.util.regex.*;
import util.gen.*;

/**
 * Prints a multi sgr file (chr position val1, val2, val3, ....) 
 */
public class MultiSGRPrinter {
	
	//fields
	private File resultsDirectory;
	private File[] intensityDirectories = null;
	private File[] chromosomeOligoPositions = null;
	private float[][] intensities;
	private 	String chromosome = null;
	private 	int[] positions;
	private int sizeOfOligo = 25;
	private int halfOligoLength;
	
	
	public MultiSGRPrinter(String[] args){
		//process args
		processArgs(args);
		
		//print file names
		System.out.println("\nOrder of column intensities:");
		Misc.printArray(intensityDirectories);
		System.out.println();
				
		//for each chromosome	
		System.out.println();
		for (int i=0; i<chromosomeOligoPositions.length; i++){
			chromosome = chromosomeOligoPositions[i].getName();
			System.out.println("Processing chromosome: "+chromosome);
		
			//get positions
			positions = (int[])IO.fetchObject(chromosomeOligoPositions[i]);
			
			//get treatment intensities float[replicas][values]
			intensities = fetchIntensities (intensityDirectories, chromosome);
			if (intensities == null) Misc.printExit("\nProblem with fetching intensities. Any missing or extra files?\n");
			if (checkSizes(intensities) == false) Misc.printExit("\nYour intensity arrays are of different lengths?!\n");
			
			try{
				File chrMSGR = new File (resultsDirectory, chromosome+".msgr");
				PrintWriter out = new PrintWriter( new FileWriter(chrMSGR));
				//for each position in the chromosome, there might be duplicate positions!
				for (int j=0; j< positions.length; j++){
					//chromosome
					StringBuffer sb = new StringBuffer (chromosome); 
					sb.append("\t");
					//position
					int pos = positions[j]+halfOligoLength;
					sb.append(pos);
					sb.append("\t");
					//values
					sb.append(intensities[0][j]);
					for (int k=1; k< intensities.length; k++){
						sb.append("\t");
						sb.append(intensities[k][j]);
					}
					out.println(sb.toString());
				}
				out.close();
			} catch (IOException e){
				e.printStackTrace();
				System.exit(0);
			}
		}
	}	
	
	public static void main(String[] args) {
		if (args.length<4){
			printDocs();
			System.exit(0);
		}	
		new MultiSGRPrinter(args);
	}		
	
	/**This method will process each argument and assign new varibles*/
	public void processArgs(String[] args){
		String intensityDirString = null;
		File oligoPositions = null;
		String resultsDirectoryString = null;
		Pattern pat = Pattern.compile("-[a-z]");
		for (int i = 0; i<args.length; i++){
			String lcArg = args[i].toLowerCase();
			Matcher mat = pat.matcher(lcArg);
			if (mat.matches()){
				char test = args[i].charAt(1);
				try{
					switch (test){
					case 't': intensityDirString = args[i+1]; i++; break;
					case 'r': resultsDirectoryString = args[i+1]; i++; break;
					case 'z': sizeOfOligo =Integer.parseInt(args[i+1]);i++; break;
					case 'o': oligoPositions = new File(args[i+1]); i++; break;
					case 'h': printDocs(); System.exit(0);
					default: Misc.printExit("\nProblem, unknown option! " + mat.group());
					}
				}
				catch (Exception e){
					Misc.printExit("\nSorry, something doesn't look right with this parameter: -"+test+"\n");
				}
			}
		}
		//look for required parameters
		if (intensityDirString == null || resultsDirectoryString == null || oligoPositions == null){
			Misc.printExit("\nPlease complete one or more of the following required parameters: -t, -o, -v, or -r .\n");
		}
		
		//parse intensities
		intensityDirectories = IO.extractFiles(intensityDirString);
		if (intensityDirectories == null) Misc.printExit("\nProblem parsing treatment directories -> "+intensityDirString);

		//parse all oligo positions
		chromosomeOligoPositions = IO.extractFiles(oligoPositions);
		if (chromosomeOligoPositions == null) Misc.printExit("\nProblem parsing oligo positions -> "+oligoPositions);
		
		resultsDirectory = new File(resultsDirectoryString);
		if (resultsDirectory.exists() == false) resultsDirectory.mkdir();
		
		halfOligoLength = (int)Math.round(((double)sizeOfOligo)/2.0);
		
	}	
	
	public static void printDocs(){ 
		System.out.println("\n" +
				"**************************************************************************************\n" +
				"**                            MultiSGRPrinter: Feb 2007                             **\n" +
				"**************************************************************************************\n" +
				"Prints a multi sgr file from processed intensities (chr pos int1 int2 int3...).\n\n"+
				
				"-o The 'OligoPositions' directory, full path, generated by MakeChromosomeSets.\n" +
				"-r The full path directory name to use in saving the results.\n" +
				"-t Chip set directories, full path, comma delimited, no spaces generated by\n" +
				"        the MakeChromosomeSets\n" +
				"-z Size of oligo, defaults to 25.\n"+
				
				"\n" +

		        "**************************************************************************************\n");		
	}

	/**Fetches a float[] from each of the directories given a fileName.  Returns null 
	 * if a file cannot be read or it is not a serialized float[].
	 * @return float[replicas][intensities]*/
	public static float[][] fetchIntensities (File[] directories, String fileName){
		float[][] intensities = new float[directories.length][];
		try {
			for (int i=0; i< directories.length; i++){
				File file = new File (directories[i], fileName);
				if (file.canRead() == false) return null;
				intensities[i] = (float[])IO.fetchObject(file);
			}
		} catch (Exception e){
			e.printStackTrace();
			return null;
		}
		return intensities;
	}
	
	/**Checks to see if the number of values are the same given float[replica#][values].*/
	public static boolean checkSizes(float[][] replicasValues){
		int size = replicasValues[0].length;
		for (int i=1; i< replicasValues.length; i++){
			if (replicasValues[i].length != size) return false;
		}
		return true;
	}
	
}
